#include <stdlib.h>
#include <stdio.h>
#include "myfunc.h"

int main(int argc, char **argv)
{
    unsigned int j = 0, write_cnt = 0, appear[16];
    int i = 0, k = 0, cur_pos_R = 0, cur_pos_S = 0, index_addr_R = 0, index_addr_S = 0;
    int write_disk = 0, write_pos = 0;
    Buffer buf_index_R, buf_index_S, buf_disk_R, buf_disk_S, buf_write;
    unsigned char *blk_index_R, *blk_index_S, *blk_disk_R, *blk_disk_S, *blk_write, temp[5] = {0};
    initBuffer(72, 64, &buf_index_R);
    initBuffer(72, 64, &buf_index_S);
    initBuffer(72, 64, &buf_disk_R);
    initBuffer(72, 64, &buf_disk_S);
    initBuffer(72, 64, &buf_write);
    blk_index_R = readBlockFromDisk(350, &buf_index_R);
    blk_index_S = readBlockFromDisk(450, &buf_index_S);
    blk_write = getNewBlockInBuffer(&buf_write);
    struct ConnectInfo info;
    info.R_num = 0;
    info.S_num = 0;
    struct Tuple tuple_R, tuple_S, tuple;
    while (1)
    {
        GetTuple(&tuple_R, cur_pos_R, blk_index_R);
        GetTuple(&tuple_S, cur_pos_S, blk_index_S);
        // printf("%d,%d\n", tuple_R.first, tuple_S.first);
        if (tuple_R.first < tuple_S.first)
        {
            // printf("R small\n");
            cur_pos_R++;
            if (cur_pos_R == 7)
            {
                freeBlockInBuffer(blk_index_R, &buf_index_R);
                index_addr_R++;
                if (index_addr_R == 7)
                {
                    break;
                }
                else
                {
                    blk_index_R = readBlockFromDisk(350 + index_addr_R, &buf_index_R);
                    cur_pos_R = 0;
                }
            }
        }
        else if (tuple_R.first > tuple_S.first)
        {
            // printf("S small\n");
            cur_pos_S++;
            if (cur_pos_S == 7)
            {
                freeBlockInBuffer(blk_index_S, &buf_index_S);
                index_addr_S++;
                if (index_addr_S == 7)
                {
                    break;
                }
                else
                {
                    blk_index_S = readBlockFromDisk(450 + index_addr_S, &buf_index_S);
                }
            }
        }
        else if (tuple_R.first == tuple_S.first)
        {
            // printf("R=S\n");
            info.R_num = 0;
            info.S_num = 0;
            i = 0;
            blk_disk_R = readBlockFromDisk(tuple_R.second, &buf_disk_R);
            j = tuple_R.second;
            GetTuple(&tuple, 0, blk_disk_R);
            while (tuple.first != tuple_R.first)
            {
                i++;
                GetTuple(&tuple, i, blk_disk_R);
            }
            while (tuple.first == tuple_R.first)
            {
                info.tuple_R[info.R_num].first = tuple.first;
                info.tuple_R[info.R_num].second = tuple.second;
                info.R_num++;
                i++;
                if (i == 7)
                {
                    j++;
                    freeBlockInBuffer(blk_disk_R, &buf_disk_R);
                    if (j <= 316)
                    {
                        blk_disk_R = readBlockFromDisk(j, &buf_disk_R);
                    }
                    else
                    {
                        break;
                    }
                    i = 0;
                }
                GetTuple(&tuple, i, blk_disk_R);
            }
            i = 0;
            blk_disk_S = readBlockFromDisk(tuple_S.second, &buf_disk_S);
            j = tuple_S.second;
            while (tuple.first != tuple_R.first)
            {
                i++;
                GetTuple(&tuple, i, blk_disk_R);
            }
            while (tuple.first == tuple_S.first)
            {
                info.tuple_S[info.S_num].first = tuple.first;
                info.tuple_S[info.S_num].second = tuple.second;
                info.S_num++;
                i++;
                if (i == 7)
                {
                    j++;
                    freeBlockInBuffer(blk_disk_S, &buf_disk_S);
                    // printf("Smark,%d\n", j);
                    if (j <= 432)
                    {

                        blk_disk_S = readBlockFromDisk(j, &buf_disk_S);
                    }
                    else
                    {
                        break;
                    }
                    i = 0;
                }
                GetTuple(&tuple, i, blk_disk_S);
            }
            for (i = 0; i < info.R_num; i++)
            {
                for (j = 0; j < info.S_num; j++)
                {
                    if (info.tuple_R[i].second == info.tuple_S[i].second)
                    {
                        if (!IsRepeat(appear, k, info.tuple_R[i].second))
                        {
                            appear[k] = info.tuple_R[i].second;
                            k++;
                            itoa(info.tuple_R[i].first, temp, 10);
                            memcpy(blk_write + write_pos * 8, temp, 4);
                            memset(temp, 0, 5);
                            itoa(info.tuple_R[i].second, temp, 10);
                            memcpy(blk_write + write_pos * 8 + 4, temp, 4);
                            memset(temp, 0, 5);
                            write_pos++;
                            if (write_pos == 8)
                            {
                                writeBlockToDisk(blk_write, RESULT6 + write_disk, &buf_write);
                                write_cnt++;
                                blk_write = getNewBlockInBuffer(&buf_write);
                                write_disk++;
                                write_pos = 0;
                            }
                        }
                    }
                }
            }

            cur_pos_R++;
            if (cur_pos_R == 7)
            {
                freeBlockInBuffer(blk_index_R, &buf_index_R);
                index_addr_R++;
                if (index_addr_R == 7)
                {
                    break;
                }
                else
                {
                    blk_index_R = readBlockFromDisk(350 + index_addr_R, &buf_index_R);
                    cur_pos_R = 0;
                }
            }
            cur_pos_S++;
            if (cur_pos_S == 7)
            {
                freeBlockInBuffer(blk_index_S, &buf_index_S);
                index_addr_S++;
                if (index_addr_S == 7)
                {
                    break;
                }
                else
                {
                    blk_index_S = readBlockFromDisk(450 + index_addr_S, &buf_index_S);
                    cur_pos_S = 0;
                }
            }
            freeBlockInBuffer(blk_disk_R, &buf_disk_R);
            freeBlockInBuffer(blk_disk_S, &buf_disk_S);
        }
    }
    if (write_pos < 8)
    {
        writeBlockToDisk(blk_write, RESULT6 + write_disk, &buf_write);
        write_cnt++;
        blk_write = getNewBlockInBuffer(&buf_write);
        write_disk++;
        write_pos = 0;
    }
    printf("total IO:%d\n", buf_disk_R.numIO +
                                buf_disk_S.numIO +
                                buf_index_R.numIO +
                                buf_index_S.numIO +
                                write_cnt);
}